﻿#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// 最大信号长度
#define MAX_SIGNAL_LEN 1024

// 多路复用函数：mode=0(同步TDM),1(统计TDM),2(FDM),3(CDM)
int multiplex(unsigned char* c, const int c_size, const unsigned char* a, const int a_len, const unsigned char* b, const int b_len, int mode) {
    if (c == NULL || a == NULL || b == NULL || c_size <= 0) return -1;
    memset(c, 0, c_size);
    int c_idx = 0;

    switch (mode) {
        // 1. 同步时分复用：固定时隙（a占奇数位，b占偶数位）
    case 0: {
        int max_len = (a_len > b_len) ? a_len : b_len;
        if (max_len * 2 > c_size) return -2; // 空间不足
        for (int i = 0; i < max_len; i++) {
            if (i < a_len) c[c_idx++] = (a[i] != 0) ? 1 : 0; // a的时隙
            if (i < b_len) c[c_idx++] = (b[i] != 0) ? 1 : 0; // b的时隙
        }
        break;
    }
          // 2. 统计时分复用：带标识（1字节标识+1字节数据，标识0=a,1=b）
    case 1: {
        int required_len = a_len * 2 + b_len * 2;
        if (required_len > c_size) return -2;
        // 加入a序列
        for (int i = 0; i < a_len; i++) {
            c[c_idx++] = 0; // 标识a
            c[c_idx++] = (a[i] != 0) ? 1 : 0; // 数据
        }
        // 加入b序列
        for (int i = 0; i < b_len; i++) {
            c[c_idx++] = 1; // 标识b
            c[c_idx++] = (b[i] != 0) ? 1 : 0; // 数据
        }
        break;
    }
          // 3. 频分复用：用不同数值表示频率（a用1/3，b用2/4，0用0）
    case 2: {
        int max_len = (a_len > b_len) ? a_len : b_len;
        if (max_len > c_size) return -2;
        for (int i = 0; i < max_len; i++) {
            unsigned char val = 0;
            if (i < a_len && a[i] != 0) val += 1; // a的频率标识
            if (i < b_len && b[i] != 0) val += 2; // b的频率标识
            c[c_idx++] = val;
        }
        break;
    }
          // 4. 码分复用：用不同编码（a用01，b用10，叠加为11）
    case 3: {
        int max_len = (a_len > b_len) ? a_len : b_len;
        if (max_len * 2 > c_size) return -2;
        for (int i = 0; i < max_len; i++) {
            unsigned char code_a = (i < a_len && a[i] != 0) ? 0x01 : 0x00;
            unsigned char code_b = (i < b_len && b[i] != 0) ? 0x02 : 0x00;
            c[c_idx++] = code_a | code_b; // 编码叠加
        }
        break;
    }
    default: return -3; // 无效模式
    }
    return c_idx; // 返回实际使用的长度
}

// 多路解复用函数：与复用模式对应
int demultiplex(unsigned char* a, const int a_size, unsigned char* b, const int b_size, const unsigned char* c, const int c_len, int mode) {
    if (a == NULL || b == NULL || c == NULL || a_size <= 0 || b_size <= 0) return -1;
    memset(a, 0, a_size);
    memset(b, 0, b_size);
    int a_idx = 0, b_idx = 0, c_idx = 0;

    switch (mode) {
        // 同步TDM解复用
    case 0: {
        while (c_idx < c_len) {
            if (a_idx < a_size) a[a_idx++] = c[c_idx++]; // 提取a的时隙
            if (c_idx >= c_len) break;
            if (b_idx < b_size) b[b_idx++] = c[c_idx++]; // 提取b的时隙
        }
        break;
    }
          // 统计TDM解复用
    case 1: {
        while (c_idx + 1 < c_len) {
            unsigned char flag = c[c_idx++];
            unsigned char data = c[c_idx++];
            if (flag == 0 && a_idx < a_size) a[a_idx++] = data; // 归属a
            else if (flag == 1 && b_idx < b_size) b[b_idx++] = data; // 归属b
        }
        break;
    }
          // 频分复用解复用
    case 2: {
        while (c_idx < c_len && (a_idx < a_size || b_idx < b_size)) {
            unsigned char val = c[c_idx++];
            if (a_idx < a_size) a[a_idx++] = (val & 1) ? 1 : 0; // 提取a的信号
            if (b_idx < b_size) b[b_idx++] = (val & 2) ? 1 : 0; // 提取b的信号
        }
        break;
    }
          // 码分解复用
    case 3: {
        while (c_idx < c_len && (a_idx < a_size || b_idx < b_size)) {
            unsigned char code = c[c_idx++];
            if (a_idx < a_size) a[a_idx++] = (code & 0x01) ? 1 : 0; // 提取a的编码
            if (b_idx < b_size) b[b_idx++] = (code & 0x02) ? 1 : 0; // 提取b的编码
        }
        break;
    }
    default: return -3;
    }
    return 0;
}

// 测试函数
int main() {
    unsigned char a[] = { 1, 0, 1, 0 }; // 消息a（非0为1）
    unsigned char b[] = { 0, 1, 0 };    // 消息b
    unsigned char c[MAX_SIGNAL_LEN];
    unsigned char a_recv[4], b_recv[3];
    int mode = 0; // 可切换0-3测试不同模式

    // 复用
    int c_len = multiplex(c, MAX_SIGNAL_LEN, a, 4, b, 3, mode);
    if (c_len < 0) {
        printf("复用失败，错误码：%d\n", c_len);
        return -1;
    }
    printf("复用后信号长度：%d\n", c_len);

    // 解复用
    int ret = demultiplex(a_recv, 4, b_recv, 3, c, c_len, mode);
    if (ret < 0) {
        printf("解复用失败，错误码：%d\n", ret);
        return -1;
    }

    // 输出结果
    printf("原始a：");
    for (int i = 0; i < 4; i++) printf("%d ", a[i]);
    printf("\n接收a：");
    for (int i = 0; i < 4; i++) printf("%d ", a_recv[i]);
    printf("\n原始b：");
    for (int i = 0; i < 3; i++) printf("%d ", b[i]);
    printf("\n接收b：");
    for (int i = 0; i < 3; i++) printf("%d ", b_recv[i]);
    return 0;
}
